<?php

namespace App\Services\SetGoldBudget;

use App\Models\User;
use App\Models\GoldRound;
use App\Models\GoldProduct;
use Brick\Math\RoundingMode;

class AssignGoldProductsFromBudgets
{
	protected $rid;
	
	public function __construct($rid)
	{
		$this->rid = $rid;
	}
	
	protected function pushToUnpaidCache(array $enteredUsers)
	{
		$rid = $this->rid;
		
		foreach ($enteredUsers as $uid) {
			
			$budgetCache = User::sGetMyBudgetCache($uid, $rid);
			$availableBudget = big_decimal($budgetCache['origin'])
				->minus($budgetCache['used'])
				->toScale(2, RoundingMode::HALF_UP);
			
			if ($p = GoldProduct::sGetFromAliveCache($rid, $availableBudget)) {
				
				$pid = array_key_first($p);
				$price = $p[$pid];
				
				if (GoldProduct::sIsInSoldCache($pid, $rid)) continue;
				
				GoldProduct::sBuyFromCache($uid, $pid, $rid);
				
				$usedBudget = big_decimal($budgetCache['used'])->plus($price)->toScale(2, RoundingMode::HALF_UP);
				
				User::sAddToBudgetCache($uid, $rid, $budgetCache['origin'], $usedBudget);
				
			} else {
				GoldRound::sDelFromGoldEnterUsersCache($uid, $rid);
				GoldRound::sAddToGoldEnterFinishedUsersCache($uid, $rid);
			}
		}
	}
	
	protected function finishLeftEnteredUsers()
	{
		$rid = $this->rid;
		
		if (GoldRound::sIsGoldEnterUsersCacheEmpty($rid)) return;
		
		$enteredUsers = GoldRound::sGetAllGoldEnterUsersCache($rid);
		
		foreach ($enteredUsers as $uid) {
			GoldRound::sDelFromGoldEnterUsersCache($uid, $rid);
			GoldRound::sAddToGoldEnterFinishedUsersCache($uid, $rid);
		}
	}
	
	protected function recallLeftGoldProducts()
	{
		if (cs('storm')->is_reclaim_soon) {
			reclaimer($this->rid)->reclaim(true);
		}
	}
	
	public function assign()
	{
		$rid = $this->rid;
		
		while (true) {
			
			if (GoldRound::sIsGoldEnterUsersCacheEmpty($rid)) break;
			if (GoldRound::sIsAliveGoldProductsCacheEmpty($rid)) break;
			
			$enteredUsers = GoldRound::sGetAllGoldEnterUsersCache($rid);
			
			$this->pushToUnpaidCache($enteredUsers);
		}
		
		$this->finishLeftEnteredUsers();
		$this->recallLeftGoldProducts();
	}
}
